/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.openwaf.client.ui.widget;

import com.openwaf.client.core.Window;
import com.openwaf.client.dom.DivElement;
import com.openwaf.client.dom.TableCellElement;
import com.openwaf.client.dom.TableElement;
import com.openwaf.client.dom.TableRowElement;
import com.openwaf.client.event.dom.ClickEvent;
import com.openwaf.client.event.dom.ClickHandler;
import com.openwaf.client.ui.UIControl;
import com.openwaf.client.ui.annotation.ViewElement;
import java.util.Date;


public class DatePicker extends UIControl {
    public static interface DateSelectHandler{
        void onDateSelect(Date d);
    }

    public static class DateString {

        public static final String[] FULL_DAYS = {"Sunday", "Monday", "Tuesday", "Wednesaday", "Thursday", "Friday", "Saturday"};
        public static final String[] SMALL_DAYS = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
        public static final String[] CHAR_DAYS = {"S", "M", "T", "W", "T", "F", "S"};
        public static final String[] SMALL_MONTHS = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
        public static final String[] FULL_MONTHS = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    }
    @ViewElement
    private DivElement divTop;
    @ViewElement
    private DivElement divLeftButton;
    @ViewElement
    private DivElement divRightButton;
    @ViewElement
    private DivElement divTitle;
    @ViewElement
    private DivElement divDays;
    @ViewElement
    private TableElement tblDays;
    private static String CSS_DAY_NAME = "waf-widget-datepicker-day-name";
    private static String CSS_DAY_NA = "waf-widget-datepicker-day-na";
    private static String CSS_DAY_NORMAL = "waf-widget-datepicker-day-normal";
    private static String CSS_DAY_SELECTED = "waf-widget-datepicker-day-selected";
    private static String CSS_DAY_TODAY = "waf-widget-datepicker-day-today";
    private TableCellElement cells[][];
    private int currentMonth;
    private int currentYear;
    private Date today;
    private Date currentStartDate;
    private Date selectedDate;
    private int lastDayInCurrentMonth;

    private DateSelectHandler selectHandler;

    public DatePicker() {
        init();
        Date d = new Date();
        today=d;
        selectedDate=d;
        currentMonth = d.getMonth();
        currentYear = d.getYear();
        drawMonth();
    }
    public DatePicker(Date currentDate){
        init();
        Date d = new Date();
        today=d;
        selectedDate=currentDate;
        currentMonth=currentDate.getMonth();
        currentYear=currentDate.getYear();
        drawMonth();
    }
     public DatePicker(String s){
        init();
        Date d = new Date();
        today=d;
        Date currentDate=null;
        try{
            currentDate=new Date(s);
        }catch(Exception e){
            currentDate=d;            
        }
        selectedDate=currentDate;
        currentMonth=currentDate.getMonth();
        currentYear=currentDate.getYear();
        drawMonth();
    }
    private void drawMonth() {
        TableCellElement cell;
        int i, j;
        for (i = 1; i < 7; i++) {
            for (j = 0; j < 7; j++) {

                cell = cells[i][j];

                cell.setCssClassName(CSS_DAY_NA);
                cell.setInnerHTML("");

            }
        }
        currentStartDate=new Date(currentYear, currentMonth, 1);
        Date curDate = new Date(currentYear, currentMonth, 1);
        String s = DateString.SMALL_MONTHS[currentMonth] + "," + (1900 + currentYear);
        divTitle.setInnerHTML(s);
        int week = 0;
        int day;
        lastDayInCurrentMonth=31;
        for (i = 1; i <= 31; i++) {
            curDate.setDate(i);
            if (curDate.getMonth() != currentMonth) {
                lastDayInCurrentMonth=i;
                break;
            }
            day = curDate.getDay();
            cell = cells[week + 1][day];
            if(compareDate(curDate,selectedDate)){
                cell.setCssClassName(CSS_DAY_SELECTED);
            }else if(compareDate(curDate,today))
            {
                cell.setCssClassName(CSS_DAY_TODAY);
            }else{
                cell.setCssClassName(CSS_DAY_NORMAL);
            }
            cell.setInnerHTML("" + i);
            if (day == 6) {
                week++;
            }
        }
    }
    private boolean compareDate(Date d1,Date d2){
        if(d1==null || d2==null) return false;
        return (d1.getYear()==d2.getYear()) && (d1.getMonth()==d2.getMonth()) && (d1.getDate()==d2.getDate());
    }

    private void reduceMonth() {
        if (currentMonth == 0) {
            currentMonth = 11;
            currentYear -= 1;
            if (currentYear < 0) {
                currentMonth = 0;
                currentYear = 0;
                return;
            }
        } else {
            currentMonth -= 1;

        }
        drawMonth();


    }

    private void incrementMonth() {
        if (currentMonth == 11) {
            currentYear += 1;
            currentMonth = 0;
        } else {
            currentMonth += 1;
        }
        drawMonth();
    }

    private void init() {
        divLeftButton.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                reduceMonth();
            }
        });
        divRightButton.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                incrementMonth();
            }
        });
        today = new Date();
        cells = new TableCellElement[6][];
        for (int i = 0; i < 7; i++) {
            cells[i] = new TableCellElement[7];
            TableRowElement row = tblDays.insertRow(i);
            for (int j = 0; j < 7; j++) {
                TableCellElement cell = row.insertCell(j);
                cells[i][j] = cell;
                if (i == 0) {
                    cell.setCssClassName(CSS_DAY_NAME);
                    cell.setInnerHTML(DateString.CHAR_DAYS[j]);
                } else {
                    cell.setCssClassName(CSS_DAY_NA);
                    final int week = i-1;
                    final int day = j;
                    cell.addClickHandler(new ClickHandler() {

                        public void onClick(ClickEvent event) {
                            onDayClick(week, day);
                        }
                    });
                }
            }
        }
    }
    public void setDateSelectHandler(DateSelectHandler handler){
        selectHandler=handler;
    }

    public void onDayClick(int w, int d) {
        int day=((w*7)+d)+1;
        if(day<=currentStartDate.getDay()){
            return;
        }
        day=day-currentStartDate.getDay();
        if(day>lastDayInCurrentMonth){
            return;
        }
        Date sel=new Date(currentStartDate.getYear(),currentStartDate.getMonth(),day);
        if(selectHandler!=null){            
            selectedDate=sel;
            selectHandler.onDateSelect(sel);
        }else{
            drawMonth();
        }
    }
    public void setSelectedDate(Date d){
        selectedDate=d;
        currentMonth = d.getMonth();
        currentYear = d.getYear();
        drawMonth();
    }
    public void setSelectedDate(String s){
        try{
            setSelectedDate(new Date(s));            
        }catch(Exception e){
            
        }
        
    }
}
